﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Controls;

namespace PlanningGIS.ArcGIS
{
    /// <summary>
    /// 查询选择操作类
    /// </summary>
    public class CursorHelper
    {
        #region 选择集、Cursor、空间搜索相关函数

        /// <summary>
        ///从selection中返回符合选择条件的要素 
        /// </summary>
        /// <param name="pFeatSelection">选择集</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <param name="sSQL">数据库查询语句</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="lFeatCount">符合条件的个数，</param>
        /// <returns></returns>
        public static ICursor GetCursorFromSelection(IFeatureSelection pFeatSelection, esriSpatialRelEnum lSpatialRelEnum, string sSQL,
                                                     IGeometry pGeometry, int lFeatCount)
        {
            if (pFeatSelection == null) return null;
            ISpatialFilter pSpatialFilter = null;
            ICursor pFeatCursor = null;

            if (sSQL.Trim() != "" || pGeometry != null)
            {
                pSpatialFilter = new SpatialFilter();
                pSpatialFilter.WhereClause = sSQL.Trim();
                if (pGeometry != null)
                {
                    if (pGeometry.IsEmpty == false)
                    {
                        ITopologicalOperator2 pTopoOperator2 = (ITopologicalOperator2)pGeometry;
                        pTopoOperator2.Simplify();
                        pSpatialFilter.SpatialRel = lSpatialRelEnum;
                        pSpatialFilter.Geometry = (IGeometry)pTopoOperator2;
                    }
                }
            }

            pFeatSelection.SelectionSet.Search(pSpatialFilter, false, out pFeatCursor);
            if (lFeatCount == 1)
            {
                lFeatCount = pFeatSelection.SelectionSet.Count;
            }
            return pFeatCursor;
        }

        /// <summary>
        /// 根据几何图形、空间关系、SQL条件查询要素
        /// </summary>
        /// <param name="pFeatCls">要素类</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <param name="sSQL">SQL条件</param>
        /// <param name="pGeometry">几何图形</param>
        /// <param name="lFeatCount">要素个数</param>
        /// <returns>要素集合</returns>
        public static IFeatureCursor GetCursorFromFeatCls(IFeatureClass pFeatCls, esriSpatialRelEnum lSpatialRelEnum, string sSQL,
                                                          IGeometry pGeometry, int lFeatCount)
        {
            if (pFeatCls == null) return null;
            ISpatialFilter pSpatialFilter = null;
            IFeatureCursor pFeatCursor = null;

            if (sSQL.Trim() != "" || pGeometry != null)
            {
                pSpatialFilter = new SpatialFilter();
                pSpatialFilter.WhereClause = sSQL.Trim();
                if (pGeometry != null)
                {
                    if (pGeometry.IsEmpty == false)
                    {
                        ITopologicalOperator2 pTopoOperator2 = (ITopologicalOperator2)pGeometry;
                        pTopoOperator2.Simplify();
                        pSpatialFilter.SpatialRel = lSpatialRelEnum;
                        pSpatialFilter.Geometry = (IGeometry)pTopoOperator2;
                    }
                }
            }
            pFeatCursor = pFeatCls.Search(pSpatialFilter, false);
            if (lFeatCount == 1)
            {
                lFeatCount = pFeatCls.FeatureCount(pSpatialFilter);
            }
            return pFeatCursor;
        }
        
        /// <summary>
        /// 根据几何图形、空间关系，SQL条件选择要素
        /// </summary>
        /// <param name="pFeatSelection">选择集</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <param name="sSQL">SQL条件</param>
        /// <param name="pGeometry">几何图形</param>
        /// <param name="lSelectionResultEnum">选择集生成方式，是否新建、追加，求异等等</param>
        /// <returns>是否成功</returns>
        public static bool SelectFeatByFilter(IFeatureSelection pFeatSelection, esriSpatialRelEnum lSpatialRelEnum, string sSQL, IGeometry pGeometry, esriSelectionResultEnum lSelectionResultEnum)
        {
            if (pFeatSelection == null) return false;
            ISpatialFilter pSpatialFilter = null;
            if (sSQL.Trim() == "" || pGeometry != null)
            {
                pSpatialFilter = new SpatialFilter();
                if (pGeometry.IsEmpty == false)
                {
                    ITopologicalOperator2 pTopoOperator2 = (ITopologicalOperator2)pGeometry;
                    pTopoOperator2.Simplify();
                    pSpatialFilter.SpatialRel = lSpatialRelEnum;
                    pSpatialFilter.Geometry = (IGeometry)pTopoOperator2;
                }
            }
            pFeatSelection.SelectFeatures(pSpatialFilter, lSelectionResultEnum, false);
            return true;
        }

        /// <summary>
        /// 通过给定图形以及缓冲大小，在指定要素类中搜索要素，并形成集合
        /// </summary>
        /// <param name="pFeatClass">要素类</param>
        /// <param name="pGeo">图形</param>
        /// <param name="width">缓冲大小</param>
        /// <param name="pAttributeFilter"></param>
        /// <returns></returns>
        public static List<IFeature> GetSelectFeatureByGeometry(IFeatureClass pFeatClass, IGeometry pGeo, double width, String pAttributeFilter = "")
        {
            List<IFeature> pFeatList = new List<IFeature>();
            if (pFeatClass == null || pGeo == null)
                return pFeatList;
            try
            {
                ITopologicalOperator pTopo = (ITopologicalOperator)pGeo;
                IGeometry pGeometry = null;

                if (width > 0)
                {
                    IPolygon pPy = (IPolygon)pTopo.Buffer(width);
                    pGeometry = pPy;
                }
                else
                {
                    pGeometry = pGeo;
                }
                ISpatialFilter pSpatialF = new SpatialFilter();
                pSpatialF.Geometry = pGeometry;
                pSpatialF.GeometryField = pFeatClass.ShapeFieldName;
                pSpatialF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                pSpatialF.WhereClause = pAttributeFilter;
                IFeatureCursor pFeatCursor = pFeatClass.Search(pSpatialF, false);

                IFeature pFeature = pFeatCursor.NextFeature();
                while (pFeature != null)
                {
                    if (!pFeatList.Contains(pFeature))
                    {
                        pFeatList.Add(pFeature);
                    }
                    pFeature = pFeatCursor.NextFeature();
                }
                Marshal.ReleaseComObject(pFeatCursor);
                return pFeatList;
            }
            catch (Exception ex)
            {
                //log.Error(ex.Message);
                //log.Error(ex.Source);
                //log.Error(ex.StackTrace);
                //return pFeatList;
                throw ex;
            }
        }
        
        /// <summary>
        /// 获取当前鼠标所在位置所有FeatureClass中的一个
        /// </summary>
        /// <param name="point"></param>
        /// <param name="map"></param>
        /// <returns></returns>
        public static IFeature GetFeature(IPoint point, IMap map)
        {
            IEnvelope env = point.Envelope; //构建geometry
            double dx = 0.00002;
            double dy = 0.00002;
            if (point.SpatialReference is IProjectedCoordinateSystem)
            {
                dx = 2;
                dy = 2;
            }
            env.Expand(dx, dy, false);
            ISpatialFilter spatialflt = new SpatialFilter();//建立搜索条件
            spatialflt.Geometry = env.ToPolygon();
            spatialflt.WhereClause = "";
            spatialflt.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            List<IFeatureLayer> layers = MapHelper.GetAllLayer<IFeatureLayer>(map);
            foreach (IFeatureLayer featlyr in layers)
            {
                if (featlyr != null)
                {
                    IFeatureClass featCls = featlyr.FeatureClass;
                    string shpFld = featCls.ShapeFieldName;
                    spatialflt.GeometryField = shpFld;
                    IFeatureCursor featCur = featCls.Search(spatialflt, false);
                    IFeature pFeat = featCur.NextFeature();
                    if (pFeat != null)
                        return pFeat;
                }
            }
            return null;
        }

        /// <summary>
        /// 返回当前ActiveView内所有要素，输入一个Number。如果要素个数超过Number，则返回一个空List以及实际个数
        /// 如果要素个数在Number内，返回符合条件的要素
        /// </summary>
        /// <param name="IMapControl3"></param>
        /// <param name="FeatLyr"></param>
        /// <param name="number"></param>
        /// <param name="pFeatList"></param>
        /// <returns></returns>
        public static int GetAllFeatureInActiveView(IMapControl3 IMapControl3, IList<IFeatureLayer> FeatLyr, int number,
                                                    ref IList<IFeature> pFeatList)
        {
            //Structure a geometry
            IEnvelope pEnv = IMapControl3.ActiveView.Extent;
            IGeometry pGeom = pEnv.ToPolygon();
            //建立搜索条件
            ISpatialFilter pSpatialF = new SpatialFilter();
            pSpatialF.Geometry = pGeom;
            pSpatialF.WhereClause = "";
            pSpatialF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            //判断所有的图层上要素数目是否超过Number
            int AllCount = 0;
            foreach (IFeatureLayer o in FeatLyr)
            {
                IFeatureClass pFeatCls = o.FeatureClass;
                String shpFld = pFeatCls.ShapeFieldName;
                //pSpatialF.GeometryField = shpFld;
                int FeatNum = o.FeatureClass.FeatureCount(pSpatialF);
                AllCount = AllCount + FeatNum;
                if (AllCount > number)
                {
                    return AllCount;
                }
            }
            ISpatialFilter pSpatialF2 = new SpatialFilter();
            pSpatialF2.Geometry = pGeom;
            pSpatialF2.WhereClause = "";
            pSpatialF2.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            //数目不超过Number，进行要素选择
            foreach (IFeatureLayer Lyr in FeatLyr)
            {
                if (Lyr != null)
                {
                    IFeatureClass pFeatCls = Lyr.FeatureClass;
                    String shpFld = pFeatCls.ShapeFieldName;
                    pSpatialF2.GeometryField = shpFld;
                    //加上下面这句话的目的是：要素本身的坐标系和当前MapControl的坐标系是可能不同的
                    //利用下面一句话可以使被选中要素输出时使用当前MapControl的坐标系！
                    pSpatialF2.set_OutputSpatialReference(shpFld, IMapControl3.SpatialReference);
                    IFeatureCursor pFeatCur = pFeatCls.Search(pSpatialF2, false);
                    IFeature pFeat = pFeatCur.NextFeature();
                    while (pFeat != null)
                    {
                        pFeatList.Add(pFeat);
                        pFeat = pFeatCur.NextFeature();
                    }
                    Marshal.ReleaseComObject(pFeatCur);
                }
            }
            return pFeatList.Count;
        }

        ///<summary>
        /// 通过在地图上点击的范围获取找到的图层名和要素的哈希表
        /// </summary>
        public static Dictionary<string, IFeature> ReturnLyrNameAndFeature(IPoint pPnt, IMapControl3 pMapControl)
        {
            Dictionary<string, IFeature> Dic = new Dictionary<string, IFeature>();
            //建立layer集合,获取当前map中的layer
            List<IFeatureLayer> Layers = MapHelper.GetAllLayer<IFeatureLayer>(pMapControl.Map);
            //构建geometry
            IEnvelope pEnv = pPnt.Envelope;
            double dx = 0.00001;
            double dy = 0.00001;
            if (pPnt.SpatialReference is IProjectedCoordinateSystem)
            {
                dx = 1;
                dy = 1;
            }
            pEnv.Expand(dx, dy, false);
            IGeometry pGeom = pEnv.ToPolygon();
            //建立搜索条件
            ISpatialFilter pSpatialF = new SpatialFilter();
            pSpatialF.Geometry = pGeom;
            pSpatialF.WhereClause = "";
            pSpatialF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            foreach (ILayer o in Layers)
            {
                IFeatureLayer pFeatLy = o as IFeatureLayer;
                if (pFeatLy != null)
                {
                    IFeatureClass pFeatCls = pFeatLy.FeatureClass;
                    String shpFld = pFeatCls.ShapeFieldName;
                    pSpatialF.GeometryField = shpFld;
                    IFeatureCursor pFeatCur = pFeatCls.Search(pSpatialF, false);
                    IFeature pFeat = pFeatCur.NextFeature();
                    if (pFeat != null)
                    {
                        Dic.Add(pFeatLy.Name, pFeat);
                    }
                }
            }
            return Dic;
        }

        /// <summary>
        /// 根据SQL条件获取选择图层中的要素
        /// </summary>
        /// <param name="pMapControl">地图数据视图</param>
        /// <param name="strSql">SQL条件</param>
        /// <param name="sPLayer">图层名</param>
        /// <returns>选择集</returns>
        public static IFeatureSelection GetFeatureSelection(IMapControl3 pMapControl, string strSql, string sPLayer)
        {
            IFeatureSelection pFeatureSelection = null;
            ILayer lyr = MapHelper.GetFirstLayer<IFeatureLayer>(pMapControl.Map, sPLayer);
            if (lyr == null) return null;
            IFeatureLayer pFeatureLayer = lyr as IFeatureLayer;
            if (pFeatureLayer == null) return null;
            pFeatureSelection = (IFeatureSelection)pFeatureLayer;
            IQueryFilter pQueryfilter = new QueryFilter();

            pQueryfilter.WhereClause = strSql;

            pFeatureSelection.SelectFeatures(pQueryfilter, esriSelectionResultEnum.esriSelectionResultNew, false);

            return pFeatureSelection;
        }

        /// <summary>
        /// 获得选择集
        /// </summary>
        /// <param name="pFeatSel">数据层</param>
        /// <param name="pGeom">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <returns></returns>
        public static ISelectionSet GetSelset(IFeatureSelection pFeatSel, IGeometry pGeom, string whereClause, esriSpatialRelEnum lSpatialRelEnum)
        {
            ISpatialFilter pSpatialFilter = new SpatialFilter();

            if (pGeom != null)
            {
                pSpatialFilter.Geometry = pGeom;
                pSpatialFilter.SpatialRel = lSpatialRelEnum;
                pSpatialFilter.GeometryField = "SHAPE";
            }

            pSpatialFilter.WhereClause = whereClause;

            try
            {
                pFeatSel.SelectFeatures(pSpatialFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
            }
            catch (COMException e)
            {
                //MessageBox.Show(e.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                //throw;

                if (e.ErrorCode == -2147216072 || e.ErrorCode == -2147216117)
                    throw new COMException("SDE连接出现异常，请重新连接数据！");
                else
                    throw;

            }
            finally
            {
                Marshal.ReleaseComObject(pSpatialFilter);
            }

            return pFeatSel.SelectionSet;
        }

        /// <summary>
        /// 得到游标（空间关系如果是面找线则用穿越；其它用相交）
        /// </summary>
        /// <param name="pFeatCls">要素类</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureClass pFeatCls, IGeometry pGeometry, string whereClause)
        {
            ISpatialFilter pSpatialFilter;
            pSpatialFilter = new SpatialFilter();
            pSpatialFilter.WhereClause = whereClause.Trim();
            ITopologicalOperator pTopoOperator2 = null;
            if (pGeometry != null)
            {
                if (pGeometry.IsEmpty == false)
                {

                    if (pGeometry.GeometryType == esriGeometryType.esriGeometryEnvelope)
                    {
                        ISegmentCollection pSegCol = (ISegmentCollection)new Polygon();
                        pSegCol.SetRectangle((IEnvelope)pGeometry);

                        IGeometry pGeomPoly = (IGeometry)pSegCol;
                        IGeoDataset pGeoDataset = (IGeoDataset)pFeatCls;
                        pGeomPoly.Project(pGeoDataset.SpatialReference);
                        pTopoOperator2 = (ITopologicalOperator)pSegCol;
                    }
                    else
                    {
                        pTopoOperator2 = (ITopologicalOperator)(pGeometry as IClone).Clone();

                    }

                    pTopoOperator2.Simplify();

                    if (pFeatCls.ShapeType == esriGeometryType.esriGeometryPolyline && pGeometry.GeometryType == esriGeometryType.esriGeometryPolygon)
                    {
                        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
                    }
                    else
                    {
                        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                    }

                    pSpatialFilter.Geometry = (IGeometry)pTopoOperator2;
                    pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;
                }
            }

            pSpatialFilter.WhereClause = whereClause;

            IFeatureCursor pFeatCursor = pFeatCls.Search(pSpatialFilter, false);

            Marshal.ReleaseComObject(pSpatialFilter);
            if (pTopoOperator2 != null) Marshal.ReleaseComObject(pTopoOperator2);

            return pFeatCursor;
        }

        /// <summary>
        /// 得到游标（空间关系如果是面找线则用穿越；其它用相交）
        /// </summary>
        /// <param name="pFeatLyr">要素层</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureLayer pFeatLyr, IGeometry pGeometry, string whereClause)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
            ISpatialFilter pSpatialFilter;
            pSpatialFilter = new SpatialFilter();
            pSpatialFilter.WhereClause = whereClause.Trim();
            ITopologicalOperator pTopoOperator2 = null;
            if (pGeometry != null)
            {
                if (pGeometry.IsEmpty == false)
                {

                    if (pGeometry.GeometryType == esriGeometryType.esriGeometryEnvelope)
                    {
                        ISegmentCollection pSegCol = (ISegmentCollection)new Polygon();
                        pSegCol.SetRectangle((IEnvelope)pGeometry);

                        IGeometry pGeomPoly = (IGeometry)pSegCol;
                        IGeoDataset pGeoDataset = (IGeoDataset)pFeatCls;
                        pGeomPoly.Project(pGeoDataset.SpatialReference);
                        pTopoOperator2 = (ITopologicalOperator)pSegCol;
                    }
                    else
                    {
                        pTopoOperator2 = (ITopologicalOperator)(pGeometry as IClone).Clone();

                    }

                    pTopoOperator2.Simplify();

                    if (pFeatCls.ShapeType == esriGeometryType.esriGeometryPolyline && pGeometry.GeometryType == esriGeometryType.esriGeometryPolygon)
                    {
                        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
                    }
                    else
                    {
                        pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                    }

                    pSpatialFilter.Geometry = (IGeometry)pTopoOperator2;
                    pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;
                }
            }

            pSpatialFilter.WhereClause = whereClause;

            IFeatureCursor pFeatCursor = pFeatLyr.Search(pSpatialFilter, false);

            Marshal.ReleaseComObject(pSpatialFilter);
            if (pTopoOperator2 != null) Marshal.ReleaseComObject(pTopoOperator2);

            return pFeatCursor;
        }

        /// <summary>
        /// 在要素类上获得游标，让用户指定空间关系
        /// </summary>
        /// <param name="pFeatCls">要素类</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureClass pFeatCls, IGeometry pGeometry, string whereClause, esriSpatialRelEnum lSpatialRelEnum)
        {
            object Missing = Type.Missing;
            ISpatialFilter pSpatialFilter;
            pSpatialFilter = new SpatialFilter();
            pSpatialFilter.WhereClause = whereClause.Trim();

            ITopologicalOperator2 pTopoOperator2 = null;
            ISegmentCollection pSegCol = null;
            IPointCollection pPntPolyline = null;

            if (pGeometry != null)
            {
                if (pGeometry.IsEmpty == false)
                {
                    IGeoDataset pGeoDataset = (IGeoDataset)pFeatCls;
                    pGeometry.Project(pGeoDataset.SpatialReference);

                    //点状图形不能转成ITopologicalOperator2，也不需要Simplify
                    if (pGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
                    {
                        pSpatialFilter.Geometry = pGeometry;
                    }
                    else
                    {
                        if (pGeometry.GeometryType == esriGeometryType.esriGeometryEnvelope)
                        {
                            pSegCol = (ISegmentCollection)new Polygon();
                            pSegCol.SetRectangle((IEnvelope)pGeometry);

                            IGeometry pGeomPoly = (IGeometry)pSegCol;

                            pGeomPoly.Project(pGeoDataset.SpatialReference);
                            pTopoOperator2 = (ITopologicalOperator2)pSegCol;
                        }
                        else if (pGeometry.GeometryType == esriGeometryType.esriGeometryPath)
                        {
                            IPointCollection pPntPath;
                            pPntPath = (IPointCollection)pGeometry;
                            pPntPolyline = (IPointCollection)new Polyline();
                            for (int i = 0; i < pPntPath.PointCount; i++)
                            {
                                pPntPolyline.AddPoint(pPntPath.get_Point(i), ref Missing, ref Missing);
                            }

                            IPolyline pPolyline = (IPolyline)pPntPolyline;
                            pPolyline.Project(pGeoDataset.SpatialReference);
                            pTopoOperator2 = (ITopologicalOperator2)pPolyline;
                        }

                        else
                        {
                            pTopoOperator2 = (ITopologicalOperator2)pGeometry;
                        }

                        pTopoOperator2.IsKnownSimple_2 = false;
                        pTopoOperator2.Simplify();
                        pSpatialFilter.Geometry = (IGeometry)pTopoOperator2;
                    }
                    pSpatialFilter.SpatialRel = lSpatialRelEnum;

                    pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;
                }
            }

            IFeatureCursor pFeatCursor = pFeatCls.Search(pSpatialFilter, false);
            Marshal.ReleaseComObject(pSpatialFilter);
            if (pSegCol != null)
                Marshal.ReleaseComObject(pSegCol);
            if (pPntPolyline != null)
                Marshal.ReleaseComObject(pPntPolyline);
            return pFeatCursor;
        }

        /// <summary>
        /// 在要素类上获得游标，让用户指定空间关系
        /// </summary>
        /// <param name="pFeatLyr">要素层</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureLayer pFeatLyr, IGeometry pGeometry, string whereClause, esriSpatialRelEnum lSpatialRelEnum)
        {
            object Missing = Type.Missing;
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
            ISpatialFilter pSpatialFilter;
            pSpatialFilter = new SpatialFilter();
            pSpatialFilter.WhereClause = whereClause.Trim();

            ITopologicalOperator2 pTopoOperator2 = null;
            ISegmentCollection pSegCol = null;
            IPointCollection pPntPolyline = null;

            if (pGeometry != null)
            {
                if (pGeometry.IsEmpty == false)
                {
                    IGeoDataset pGeoDataset = (IGeoDataset)pFeatCls;
                    pGeometry.Project(pGeoDataset.SpatialReference);

                    //点状图形不能转成ITopologicalOperator2，也不需要Simplify
                    if (pGeometry.GeometryType == esriGeometryType.esriGeometryPoint)
                    {
                        pSpatialFilter.Geometry = pGeometry;
                    }
                    else
                    {
                        if (pGeometry.GeometryType == esriGeometryType.esriGeometryEnvelope)
                        {
                            pSegCol = (ISegmentCollection)new Polygon();
                            pSegCol.SetRectangle((IEnvelope)pGeometry);

                            IGeometry pGeomPoly = (IGeometry)pSegCol;

                            pGeomPoly.Project(pGeoDataset.SpatialReference);
                            pTopoOperator2 = (ITopologicalOperator2)pSegCol;
                        }
                        else if (pGeometry.GeometryType == esriGeometryType.esriGeometryPath)
                        {
                            IPointCollection pPntPath;
                            pPntPath = (IPointCollection)pGeometry;
                            pPntPolyline = (IPointCollection)new Polyline();
                            for (int i = 0; i < pPntPath.PointCount; i++)
                            {
                                pPntPolyline.AddPoint(pPntPath.get_Point(i), ref Missing, ref Missing);
                            }

                            IPolyline pPolyline = (IPolyline)pPntPolyline;
                            pPolyline.Project(pGeoDataset.SpatialReference);
                            pTopoOperator2 = (ITopologicalOperator2)pPolyline;
                        }

                        else
                        {
                            pTopoOperator2 = (ITopologicalOperator2)pGeometry;
                        }

                        pTopoOperator2.IsKnownSimple_2 = false;
                        pTopoOperator2.Simplify();
                        pSpatialFilter.Geometry = (IGeometry)pTopoOperator2;
                    }
                    pSpatialFilter.SpatialRel = lSpatialRelEnum;

                    pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;
                }
            }

            IFeatureCursor pFeatCursor = pFeatLyr.Search(pSpatialFilter, false);
            Marshal.ReleaseComObject(pSpatialFilter);
            if (pSegCol != null)
                Marshal.ReleaseComObject(pSegCol);
            if (pPntPolyline != null)
                Marshal.ReleaseComObject(pPntPolyline);
            return pFeatCursor;
        }

        /// <summary>
        /// 在选择集上获得游标，如果选择集输入小于1000则在选择集上做Search，大于10000则在要素类上做Search，可以提高效率
        /// </summary>
        /// <param name="pFeatCls">要素类</param>
        /// <param name="pSelset">已有选择集</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureClass pFeatCls, ISelectionSet pSelset, IGeometry pGeometry, string whereClause)
        {
            ISpatialFilter pSpatialFilter = new SpatialFilter();
            IFeatureCursor pFeatCursor;

            if (pFeatCls.ShapeType == esriGeometryType.esriGeometryPolyline && pGeometry.GeometryType == esriGeometryType.esriGeometryPolygon)
            {
                pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
            }
            else
            {
                pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            }

            pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;
            pSpatialFilter.Geometry = pGeometry;
            pSpatialFilter.WhereClause = whereClause;

            if (pSelset.Count < 1000)
            {
                ICursor pCursor;
                pSelset.Search(pSpatialFilter, false, out pCursor);
                pFeatCursor = (IFeatureCursor)pCursor;
            }
            else
            {
                pFeatCursor = pFeatCls.Search(pSpatialFilter, false);
            }

            return pFeatCursor;
        }

        /// <summary>
        /// 在选择集上获得游标，如果选择集输入小于1000则在选择集上做Search，大于10000则在要素类上做Search，可以提高效率
        /// </summary>
        /// <param name="pFeatLyr">要素层</param>
        /// <param name="pSelset">已有选择集</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureLayer pFeatLyr, ISelectionSet pSelset, IGeometry pGeometry, string whereClause)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
            ISpatialFilter pSpatialFilter = new SpatialFilter();
            IFeatureCursor pFeatCursor;

            if (pFeatCls.ShapeType == esriGeometryType.esriGeometryPolyline && pGeometry.GeometryType == esriGeometryType.esriGeometryPolygon)
            {
                pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
            }
            else
            {
                pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            }

            pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;
            pSpatialFilter.Geometry = pGeometry;
            pSpatialFilter.WhereClause = whereClause;

            if (pSelset.Count < 1000)
            {
                ICursor pCursor;
                pSelset.Search(pSpatialFilter, false, out pCursor);
                pFeatCursor = (IFeatureCursor)pCursor;
            }
            else
            {
                pFeatCursor = pFeatLyr.Search(pSpatialFilter, false);
            }

            return pFeatCursor;
        }

        /// <summary>
        /// 在选择集上获得游标，如果选择集输入小于1000则在选择集上做Search，大于1000则在要素类上做Search，并让用户指定空间关系
        /// </summary>
        /// <param name="pFeatCls">要素类</param>
        /// <param name="pSelset">已有选择集</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureClass pFeatCls, ISelectionSet pSelset, IGeometry pGeometry, string whereClause, esriSpatialRelEnum lSpatialRelEnum)
        {
            ISpatialFilter pSpatialFilter = new SpatialFilter();
            IFeatureCursor pFeatCursor;

            pSpatialFilter.SpatialRel = lSpatialRelEnum;

            pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;

            pSpatialFilter.WhereClause = whereClause;

            if (pSelset.Count < 1000)
            {
                ICursor pCursor;
                pSelset.Search(pSpatialFilter, false, out pCursor);
                pFeatCursor = (IFeatureCursor)pCursor;
            }
            else
            {
                pFeatCursor = pFeatCls.Search(pSpatialFilter, false);
            }

            return pFeatCursor;
        }

        /// <summary>
        /// 在选择集上获得游标，如果选择集输入小于1000则在选择集上做Search，大于1000则在要素类上做Search，并让用户指定空间关系
        /// </summary>
        /// <param name="pFeatLyr">要素层</param>
        /// <param name="pSelset">已有选择集</param>
        /// <param name="pGeometry">空间过滤条件</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <param name="lSpatialRelEnum">空间关系</param>
        /// <returns></returns>
        public static IFeatureCursor GetCursor(IFeatureLayer pFeatLyr, ISelectionSet pSelset, IGeometry pGeometry, string whereClause, esriSpatialRelEnum lSpatialRelEnum)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
            ISpatialFilter pSpatialFilter = new SpatialFilter();
            IFeatureCursor pFeatCursor;

            pSpatialFilter.SpatialRel = lSpatialRelEnum;

            pSpatialFilter.GeometryField = pFeatCls.ShapeFieldName;

            pSpatialFilter.WhereClause = whereClause;

            if (pSelset.Count < 1000)
            {
                ICursor pCursor;
                pSelset.Search(pSpatialFilter, false, out pCursor);
                pFeatCursor = (IFeatureCursor)pCursor;
            }
            else
            {
                pFeatCursor = pFeatLyr.Search(pSpatialFilter, false);
            }

            return pFeatCursor;
        }

        

        #endregion

    }
}
